/**
 * @file 03_mmap.c
 * @author your name (you@domain.com)
 * @brief 演示映射到指定地址
 * @version 0.1
 * @date 2023-02-28
 *
 * @copyright Copyright (c) 2023
 *
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    int fd = open("./03_mmap.c", O_RDONLY);
    int len = 1024;

    {
        //对x64来说，用户态虚拟地址范围为0~0x7fff ffff ffff，所以0x1 0000 0000 0000是一个非法的用户态虚拟地址
        void* p1 = mmap((void*)0x1000000000000, len, PROT_READ, MAP_PRIVATE, fd, 0);
        printf("p1 = %p\n", p1);
        char str[100] = {0};
        memcpy(str, p1, 99);
        printf("read: %s\n", str);
        munmap(p1, len);
    }

    {
        void* p1 = mmap((void*)0x100000000000, len, PROT_READ, MAP_PRIVATE, fd, 0);
        printf("p1 = %p\n", p1);
        char str[100] = {0};
        memcpy(str, p1, 99);
        printf("read: %s\n", str);
        munmap(p1, len);
    }

    {
        int len = 100;
        //实际映射时会把len对齐到PAGE SIZE，所以映射100字节但读取200字节，仍然可以读取到数据。
        //前提是文件长度>len。
        void* p1 = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
        printf("p1 = %p\n", p1);
        char str[200] = {0};
        memcpy(str, p1, 199);
        printf("read: %s\n", str);
        munmap(p1, len);
    }

    close(fd);
}

